﻿using System;
using System.Collections.Generic;
using System.Linq;



namespace CarTrackr.Data
{
    public class EntityFrameworkRepository :IRepository
    {
        private CarTrackrDbEntities entities;

        public  EntityFrameworkRepository()
        {
            entities = new CarTrackrDbEntities();
        }


        #region User

        public List<T> ListUsers<T>()
        {
            var userEntities = from userEntity in entities.UserEntitySet
                               select userEntity;

            List<T> users = new List<T>();

            foreach(UserEntity userEntity in userEntities)
            {

                users.Add(Converter.ToBusinessBase<T>(userEntity));
            }

            return users; 
        }


        public T GetUserByName<T>(string userName)
        {
          

            UserEntity found = (from userEntity in entities.UserEntitySet
                                where userEntity.UserName == userName
                                select userEntity).FirstOrDefault();


        
            return Converter.ToBusinessBase<T>( found);

        }

     

        #endregion

        #region Car
        public List<T> ListCars<T>(Guid userId)
        {
       
            List<CarEntity> found = (from carEntity in entities.CarEntitySet
                                    where carEntity.UserEntity.UserId == userId
                                    select carEntity).ToList();

            var cars = new List<T>();

            foreach(CarEntity entity in found)
            {
                var car = Converter.ToBusinessBase<T>(entity);

                cars.Add(car);

            }

            return cars;
        }


        public T GetCarById<T>(Guid id)
        {
          
            CarEntity found = (from carEntity in entities.CarEntitySet
                                where carEntity.Id  == id
                                select carEntity).FirstOrDefault();

           var car = Converter.ToBusinessBase<T>(found);

            return car;
        }

        public T GetCarByLicensePlate<T>(string licensePlate)
        {
         
            CarEntity found = (from carEntity in entities.CarEntitySet
                               where carEntity.LicensePlate == licensePlate
                               select carEntity).FirstOrDefault();

            var car = Converter.ToBusinessBase<T>(found);
 
            return car;
        }

     
        public void AddCar<T>(T car,Guid userId)
        {

            UserEntity user  = (from entity in entities.UserEntitySet
                                where entity.UserId == userId
                                select entity).FirstOrDefault();

            var carEntity = Converter.ToEntity<CarEntity>(car);

            carEntity.UserEntity = user; 

            entities.AddToCarEntitySet(carEntity);

            entities.SaveChanges();

        }

        public void UpdateCar<T>(T car)
        {
            CarEntity carEntityChanged =Converter.ToEntity<CarEntity>(car);

            Guid carId = carEntityChanged.Id;

            CarEntity original = GetCarEntityById(carId);

            entities.ApplyPropertyChanges(original.EntityKey.EntitySetName, carEntityChanged);

            entities.SaveChanges();

        }




        public void RemoveCar(Guid id)
        {
            CarEntity original = GetCarEntityById(id);
            entities.DeleteObject(original);

            entities.SaveChanges();

        }

        private CarEntity GetCarEntityById(Guid id)
        {
            return (from carEntity in entities.CarEntitySet
                    where carEntity.Id == id
                    select carEntity).FirstOrDefault();
        }


        #endregion

        #region  Refuelling

        public List<T> ListRefuellings<T>(Guid carId)
        {
          

            List<RefuellingEntity> found = (from refuellingEntity in entities.RefuellingEntitySet
                                            where refuellingEntity.CarEntity.Id ==carId
                                            orderby refuellingEntity.Date descending
                                            select refuellingEntity).ToList();

            var refuellings = new List<T>();

            foreach (RefuellingEntity entity in found)
            {
                refuellings.Add(Converter.ToBusinessBase<T>(entity));
            }

            return refuellings; 
            
          
        }



        public void AddRefuelling<T>(T refuelling,Guid carId)
        {
            
            CarEntity carEntity = GetCarEntityById(carId);

            var refuellingEntity = Converter.ToEntity<RefuellingEntity>(refuelling);

            refuellingEntity.CarEntity = carEntity;

            entities.AddToRefuellingEntitySet(refuellingEntity);

            entities.SaveChanges();

        }

        public void RemoveRefuelling(Guid id)
        {
            RefuellingEntity refuellingEntity = GetRefuellingEntityById(id);

            entities.DeleteObject(refuellingEntity);

            entities.SaveChanges();

        }


        private RefuellingEntity GetRefuellingEntityById(Guid id)
        {
            return (from refuellingEntity in entities.RefuellingEntitySet
                    where refuellingEntity.Id == id
                    select refuellingEntity).FirstOrDefault();
        }

        #endregion

    }
}
